home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / daemons / lprm_fix.z / lprm_fix / lpr / common_source / displayq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-04  |  9.7 KB  |  426 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)displayq.c    5.13 (Berkeley) 6/1/90";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * Routines to display the state of the queue.
  40.  */
  41.  
  42. #include "lp.h"
  43. #include "pathnames.h"
  44.  
  45. #define JOBCOL    40        /* column for job # in -l format */
  46. #define OWNCOL    7        /* start of Owner column in normal */
  47. #define SIZCOL    62        /* start of Size column in normal */
  48.  
  49. /*
  50.  * Stuff for handling job specifications
  51.  */
  52. extern char    *user[];    /* users to process */
  53. extern int    users;        /* # of users in user array */
  54. extern int    requ[];        /* job number of spool entries */
  55. extern int    requests;    /* # of spool requests */
  56.  
  57. int    lflag;        /* long output option */
  58. char    current[40];    /* current file being printed */
  59. int    garbage;    /* # of garbage cf files */
  60. int    rank;        /* order to be printed (-1=none, 0=active) */
  61. long    totsize;    /* total print job size in bytes */
  62. int    first;        /* first file in ``files'' column? */
  63. int    col;        /* column on screen */
  64. char    file[132];    /* print file name */
  65.  
  66. char    *head0 = "Rank   Owner      Job  Files";
  67. char    *head1 = "Total Size\n";
  68.  
  69. /*
  70.  * Display the current state of the queue. Format = 1 if long format.
  71.  */
  72. displayq(format)
  73.     int format;
  74. {
  75.     register struct queue *q;
  76.     register int i, nitems, fd;
  77.     register char    *cp;
  78.     struct queue **queue;
  79.     struct stat statb;
  80.     FILE *fp;
  81.     char c;
  82.  
  83.     lflag = format;
  84.     totsize = 0;
  85.     rank = -1;
  86.  
  87.     if ((i = pgetent(line, printer)) < 0)
  88.         fatal("cannot open printer description file");
  89.     else if (i == 0)
  90.         fatal("unknown printer");
  91.     if ((LP = pgetstr("lp", &bp)) == NULL)
  92.         LP = _PATH_DEFDEVLP;
  93.     if ((RP = pgetstr("rp", &bp)) == NULL)
  94.         RP = DEFLP;
  95.     if ((SD = pgetstr("sd", &bp)) == NULL)
  96.         SD = _PATH_DEFSPOOL;
  97.     if ((LO = pgetstr("lo", &bp)) == NULL)
  98.         LO = DEFLOCK;
  99.     if ((ST = pgetstr("st", &bp)) == NULL)
  100.         ST = DEFSTAT;
  101.     RM = pgetstr("rm", &bp);
  102.     if (cp = checkremote())
  103.         printf("Warning: %s\n", cp);
  104.  
  105.     /*
  106.      * Print out local queue
  107.      * Find all the control files in the spooling directory
  108.      */
  109.     if (chdir(SD) < 0)
  110.         fatal("cannot chdir to spooling directory");
  111.     if ((nitems = getq(&queue)) < 0)
  112.         fatal("cannot examine spooling area\n");
  113.     if (stat(LO, &statb) >= 0) {
  114.         if (statb.st_mode & 0100) {
  115.             if (sendtorem)
  116.                 printf("%s: ", host);
  117.             printf("Warning: %s is down: ", printer);
  118.             fd = open(ST, O_RDONLY);
  119.             if (fd >= 0) {
  120.                 (void) flock(fd, LOCK_SH);
  121.                 while ((i = read(fd, line, sizeof(line))) > 0)
  122.                     (void) fwrite(line, 1, i, stdout);
  123.                 (void) close(fd);    /* unlocks as well */
  124.             } else
  125.                 putchar('\n');
  126.         }
  127.         if (statb.st_mode & 010) {
  128.             if (sendtorem)
  129.                 printf("%s: ", host);
  130.             printf("Warning: %s queue is turned off\n", printer);
  131.         }
  132.     }
  133.  
  134.     if (nitems) {
  135.         fp = fopen(LO, "r");
  136.         if (fp == NULL)
  137.             warn();
  138.         else {
  139.             /* get daemon pid */
  140.             cp = current;
  141.             while ((*cp = getc(fp)) != EOF && *cp != '\n')
  142.                 cp++;
  143.             *cp = '\0';
  144.             i = atoi(current);
  145.             if (i <= 0 || kill(i, 0) < 0)
  146.                 warn();
  147.             else {
  148.                 /* read current file name */
  149.                 cp = current;
  150.                 while ((*cp = getc(fp)) != EOF && *cp != '\n')
  151.                     cp++;
  152.                 *cp = '\0';
  153.                 /*
  154.                  * Print the status file.
  155.                  */
  156.                 if (sendtorem)
  157.                     printf("%s: ", host);
  158.                 fd = open(ST, O_RDONLY);
  159.                 if (fd >= 0) {
  160.                     (void) flock(fd, LOCK_SH);
  161.                     while ((i = read(fd, line, sizeof(line))) > 0)
  162.                         (void) fwrite(line, 1, i, stdout);
  163.                     (void) close(fd);    /* unlocks as well */
  164.                 } else
  165.                     putchar('\n');
  166.             }
  167.             (void) fclose(fp);
  168.         }
  169.         /*
  170.          * Now, examine the control files and print out the jobs to
  171.          * be done for each user.
  172.          */
  173.         if (!lflag)
  174.             header();
  175.         for (i = 0; i < nitems; i++) {
  176.             q = queue[i];
  177.             inform(q->q_name);
  178.             free(q);
  179.         }
  180.         free(queue);
  181.     }
  182.     if (!sendtorem) {
  183.         if (nitems == 0)
  184.             puts("no entries");
  185.         return;
  186.     }
  187.  
  188.     /*
  189.      * Print foreign queue
  190.      * Note that a file in transit may show up in either queue.
  191.      */
  192.     if (nitems)
  193.         putchar('\n');
  194.     (void) sprintf(line, "%c%s", format + '\3', RP);
  195.     cp = line;
  196.     for (i = 0; i < requests; i++) {
  197.         cp += strlen(cp);
  198.         (void) sprintf(cp, " %d", requ[i]);
  199.     }
  200.     for (i = 0; i < users; i++) {
  201.         cp += strlen(cp);
  202.         *cp++ = ' ';
  203.         (void) strcpy(cp, user[i]);
  204.     }
  205.     strcat(line, "\n");
  206.     fd = getport(RM);
  207.     if (fd < 0) {
  208.         if (from != host)
  209.             printf("%s: ", host);
  210.         printf("connection to %s is down\n", RM);
  211.     }
  212.     else {
  213.         i = strlen(line);
  214.         if (write(fd, line, i) != i)
  215.             fatal("Lost connection");
  216.         while ((i = read(fd, line, sizeof(line))) > 0)
  217.             (void) fwrite(line, 1, i, stdout);
  218.         (void) close(fd);
  219.     }
  220. }
  221.  
  222. /*
  223.  * Print a warning message if there is no daemon present.
  224.  */
  225. warn()
  226. {
  227.     if (sendtorem)
  228.         printf("\n%s: ", host);
  229.     puts("Warning: no daemon present");
  230.     current[0] = '\0';
  231. }
  232.  
  233. /*
  234.  * Print the header for the short listing format
  235.  */
  236. header()
  237. {
  238.     printf(head0);
  239.     col = strlen(head0)+1;
  240.     blankfill(SIZCOL);
  241.     printf(head1);
  242. }
  243.  
  244. inform(cf)
  245.     char *cf;
  246. {
  247.     register int j, k;
  248.     register char *cp;
  249.     FILE *cfp;
  250.  
  251.     /*
  252.      * There's a chance the control file has gone away
  253.      * in the meantime; if this is the case just keep going
  254.      */
  255.     if ((cfp = fopen(cf, "r")) == NULL)
  256.         return;
  257.  
  258.     if (rank < 0)
  259.         rank = 0;
  260.     if (sendtorem || garbage || strcmp(cf, current))
  261.         rank++;
  262.     j = 0;
  263.     while (getline(cfp)) {
  264.         switch (line[0]) {
  265.         case 'P': /* Was this file specified in the user's list? */
  266.             if (!inlist(line+1, cf)) {
  267.                 fclose(cfp);
  268.                 return;
  269.             }
  270.             if (lflag) {
  271.                 printf("\n%s: ", line+1);
  272.                 col = strlen(line+1) + 2;
  273.                 prank(rank);
  274.                 blankfill(JOBCOL);
  275.                 printf(" [job %s]\n", cf+3);
  276.             } else {
  277.                 col = 0;
  278.                 prank(rank);
  279.                 blankfill(OWNCOL);
  280.                 printf("%-10s %-3d  ", line+1, atoi(cf+3));
  281.                 col += 16;
  282.                 first = 1;
  283.             }
  284.             continue;
  285.         default: /* some format specifer and file name? */
  286.             if (line[0] < 'a' || line[0] > 'z')
  287.                 continue;
  288.             if (j == 0 || strcmp(file, line+1) != 0)
  289.                 (void) strcpy(file, line+1);
  290.             j++;
  291.             continue;
  292.         case 'N':
  293.             show(line+1, file, j);
  294.             file[0] = '\0';
  295.             j = 0;
  296.         }
  297.     }
  298.     fclose(cfp);
  299.     if (!lflag) {
  300.         blankfill(SIZCOL);
  301.         printf("%ld bytes\n", totsize);
  302.         totsize = 0;
  303.     }
  304. }
  305.  
  306. inlist(name, file)
  307.     char *name, *file;
  308. {
  309.     register int *r, n;
  310.     register char **u, *cp;
  311.  
  312.     if (users == 0 && requests == 0)
  313.         return(1);
  314.     /*
  315.      * Check to see if it's in the user list
  316.      */
  317.     for (u = user; u < &user[users]; u++)
  318.         if (!strcmp(*u, name))
  319.             return(1);
  320.     /*
  321.      * Check the request list
  322.      */
  323.     for (n = 0, cp = file+3; isdigit(*cp); )
  324.         n = n * 10 + (*cp++ - '0');
  325.     for (r = requ; r < &requ[requests]; r++)
  326.         if (*r == n && !strcmp(cp, from))
  327.             return(1);
  328.     return(0);
  329. }
  330.  
  331. show(nfile, file, copies)
  332.     register char *nfile, *file;
  333. {
  334.     if (strcmp(nfile, " ") == 0)
  335.         nfile = "(standard input)";
  336.     if (lflag)
  337.         ldump(nfile, file, copies);
  338.     else
  339.         dump(nfile, file, copies);
  340. }
  341.  
  342. /*
  343.  * Fill the line with blanks to the specified column
  344.  */
  345. blankfill(n)
  346.     register int n;
  347. {
  348.     while (col++ < n)
  349.         putchar(' ');
  350. }
  351.  
  352. /*
  353.  * Give the abbreviated dump of the file names
  354.  */
  355. dump(nfile, file, copies)
  356.     char *nfile, *file;
  357. {
  358.     register short n, fill;
  359.     struct stat lbuf;
  360.  
  361.     /*
  362.      * Print as many files as will fit
  363.      *  (leaving room for the total size)
  364.      */
  365.      fill = first ? 0 : 2;    /* fill space for ``, '' */
  366.      if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
  367.         if (col < SIZCOL) {
  368.             printf(" ..."), col += 4;
  369.             blankfill(SIZCOL);
  370.         }
  371.     } else {
  372.         if (first)
  373.             first = 0;
  374.         else
  375.             printf(", ");
  376.         printf("%s", nfile);
  377.         col += n+fill;
  378.     }
  379.     if (*file && !stat(file, &lbuf))
  380.         totsize += copies * lbuf.st_size;
  381. }
  382.  
  383. /*
  384.  * Print the long info about the file
  385.  */
  386. ldump(nfile, file, copies)
  387.     char *nfile, *file;
  388. {
  389.     struct stat lbuf;
  390.  
  391.     putchar('\t');
  392.     if (copies > 1)
  393.         printf("%-2d copies of %-19s", copies, nfile);
  394.     else
  395.         printf("%-32s", nfile);
  396.     if (*file && !stat(file, &lbuf))
  397.         printf(" %ld bytes", lbuf.st_size);
  398.     else
  399.         printf(" ??? bytes");
  400.     putchar('\n');
  401. }
  402.  
  403. /*
  404.  * Print the job's rank in the queue,
  405.  *   update col for screen management
  406.  */
  407. prank(n)
  408. {
  409.     char line[100];
  410.     static char *r[] = {
  411.         "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
  412.     };
  413.  
  414.     if (n == 0) {
  415.         printf("active");
  416.         col += 6;
  417.         return;
  418.     }
  419.     if ((n/10)%10 == 1)
  420.         (void) sprintf(line, "%dth", n);
  421.     else
  422.         (void) sprintf(line, "%d%s", n, r[n%10]);
  423.     col += strlen(line);
  424.     printf("%s", line);
  425. }
  426.